package com.ColonyCount.View;

import com.ColonyCount.ColonyCountHeap;
import com.ColonyCount.Activity.ThresholdActivity;
import com.ColonyCount.Image.Image8;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

public class ThresholdView extends View {
	
	Bitmap sourceBitmap;
	Image8 lumaMap;
    int threshold;
    float scale = -1.0f;
    int canvasPosX = 0;
    int canvasPosY = 0;
    int activePointerId = -1;
    float lastPointerX;
    float lastPointerY;
    ScaleGestureDetector mScaleDetector;
    
	public ThresholdView(Context context) 
	{
		super(context);
	}
	
	public ThresholdView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }

	public void setSourceBitmap(Bitmap sourceBitmap)
	{
		this.sourceBitmap = sourceBitmap;
		invalidate();
	}

	public void setLumaMap(Image8 lumaMap)
	{
		this.lumaMap = lumaMap;
		invalidate();
	}

	public void setThreshold(int threshold)
	{
		this.threshold = threshold;
		invalidate();
	}
	
	void CanvasScale(float deltaScale, float focusX, float focusY)
	{
		if(scale == -1.0f)
			return;
		
        float oldX = focusX*scale + canvasPosX;
        float oldY = focusY*scale + canvasPosY;

        float dX = (focusX*scale + canvasPosX)*deltaScale;
        float dY = (focusY*scale + canvasPosY)*deltaScale;

        
		float newScale = scale*deltaScale;
        scale = Math.max(0.1f, Math.min(newScale, 5.0f));

        float minScaleX = (float)getWidth()/(float)sourceBitmap.getWidth();
        float minScaleY= (float)getHeight()/(float)sourceBitmap.getHeight();
        scale = Math.max(scale, Math.min(minScaleX, minScaleY));

        float newX = focusX*scale + canvasPosX;
        float newY = focusY*scale + canvasPosY;

        float deltaX = oldX - newX;
        float deltaY = oldY - newY;
        
        CanvasMove(dX, dY);
	}
	
	void CanvasMove(float deltaX, float deltaY)
	{
		if(scale == -1.0f)
			return;
		
		canvasPosX += deltaX;
        canvasPosY += deltaY;
        
        // Clamp pos
        int minX = getWidth() - (int)((float)sourceBitmap.getWidth()*scale);
        int minY = getHeight() - (int)((float)sourceBitmap.getHeight()*scale);
        canvasPosX = Math.max(canvasPosX, minX);
        canvasPosY = Math.max(canvasPosY, minY);
        canvasPosX = Math.min(canvasPosX, 0);
        canvasPosY = Math.min(canvasPosY, 0);
	}
	
	@Override
	protected void onDraw (Canvas canvas)
	{
		if(sourceBitmap == null)
			return;

		if(scale == -1.0f)
		{
			float widthScale = (float)getWidth()/(float)sourceBitmap.getWidth();
			float heightScale = (float)getHeight()/(float)sourceBitmap.getHeight();
			scale = Math.min(widthScale, heightScale);
		}

		canvas.save();
		canvas.translate(canvasPosX, canvasPosY);
		canvas.scale(scale, scale);
	
		Paint paint = new Paint();
		paint.setAntiAlias(false);
		paint.setFilterBitmap(false);
		paint.setDither(false);
	    	
//        	float[] array = new float[20];
//        	array[3] = 1.0f;
//        	array[8] = 1.0f;
//        	array[13] = 1.0f;
//        	ColorMatrix colorMatrix = new ColorMatrix(array);
//        	paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
		paint.setColor(0xFFFFFFFF);
//        	paint.setAlpha(0xFF);
    	
    	
//        	canvas.drawColor(Color.WHITE);
    	
		canvas.drawBitmap(sourceBitmap, 0, 0, paint);
    	
    	
//        	float aspect = (float)sourceBitmap.getHeight()/(float)sourceBitmap.getWidth();
//        	Rect targetRect = new Rect(0,0, canvas.getWidth(), (int)((float)canvas.getWidth()*aspect));
//    		canvas.drawBitmap(sourceBitmap, targetRect, new Rect(0,0,sourceBitmap.getWidth(),sourceBitmap.getHeight()), paint);

		paint.setColor(Color.GREEN);
		float[] array = { 	
				0, 0, 0, 0, 0, 
				0, 0, 0, 0, 255,
				0, 0, 0, 0, 0,
				-128, 0, 0, 0, 128*threshold };
		ColorMatrix colorMatrix = new ColorMatrix(array);
		paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
		canvas.drawBitmap(sourceBitmap, 0, 0, paint);
		
//    	if(lumaMap != null)
//    	{
//        	int width = canvas.getWidth();
//        	int height = canvas.getHeight();
//        	byte[] lumaPixes = lumaMap.getPixels();
//        	Paint paint = new Paint();
//        	paint.setColor(0xFF00FF00);
//        	paint.setStrokeWidth(1);
//        	int offset = 0;
//        	for(int y=0;y<height;y++)
//        	{
//        		for(int x=0;x<width;x++)
//        		{
//        			int value = lumaPixes[offset] & 0xFF;
//        			offset ++;
//        			if(value < threshold)
//            		{
//        				canvas.drawPoint(x,y , paint);
//            		}
//        		}
//        	}
//    	}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
	    // Let the ScaleGestureDetector inspect all events.
	    mScaleDetector.onTouchEvent(ev);
	    
	    final int action = ev.getAction();
	    switch (action & MotionEvent.ACTION_MASK) {
	    case MotionEvent.ACTION_DOWN: {
	        final float x = ev.getX();
	        final float y = ev.getY();
	        
	        lastPointerX = x;
	        lastPointerY = y;
	        activePointerId = ev.getPointerId(0);
	        break;
	    }
	        
	    case MotionEvent.ACTION_MOVE: {
	        final int pointerIndex = ev.findPointerIndex(activePointerId);
	        final float x = ev.getX(pointerIndex);
	        final float y = ev.getY(pointerIndex);

	        // Only move if the ScaleGestureDetector isn't processing a gesture.
	        if (!mScaleDetector.isInProgress()) {
	            final float dx = x - lastPointerX;
	            final float dy = y - lastPointerY;

	            CanvasMove(dx, dy);

	            invalidate();
	        }

	        lastPointerX = x;
	        lastPointerY = y;

	        break;
	    }
	        
	    case MotionEvent.ACTION_UP: {
	    	activePointerId = -1;
	        break;
	    }
	        
	    case MotionEvent.ACTION_CANCEL: {
	    	activePointerId = -1;
	        break;
	    }
	    
	    case MotionEvent.ACTION_POINTER_UP: {
	        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
	                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
	        final int pointerId = ev.getPointerId(pointerIndex);
	        if (pointerId == activePointerId) {
	            // This was our active pointer going up. Choose a new
	            // active pointer and adjust accordingly.
	            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
	            lastPointerX = ev.getX(newPointerIndex);
	            lastPointerY = ev.getY(newPointerIndex);
	            activePointerId = ev.getPointerId(newPointerIndex);
	        }
	        break;
	    }
	    }
	    
	    return true;
	}

    
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
        	
        	float scaleFactor = detector.getScaleFactor();
            float focusX = detector.getFocusX();
            float focusY = detector.getFocusY();
            
            CanvasScale(scaleFactor, focusX, focusY);
            


//            canvasPosX -= focusX*scaleFactor;
//            canvasPosY -= focusY*scaleFactor;
//            
//            MoveCanvasPos(dx, dy);
            
            invalidate();
            return true;
        }
    }
}
